﻿using Core.Tools;
using System;

namespace Core.Entities
{
    /// <summary>
    /// 运行时函数参数签名标识
    /// </summary>
    public sealed class RuntimeMethodSign
    {
        /// <summary>
        /// 构造运行时函数参数签名标识
        /// </summary>
        /// <param name="Name">函数名称</param>
        /// <param name="Params">函数的参数</param>
        public RuntimeMethodSign(string Name, object[] Params)
        {
            InternalName = Name;
            InternalParams = Params;
            HashCode = Name.GetHashCode() ^ (46104728 * Params.Length);

            IsInputParams = true;
        }

        /// <summary>
        /// 构造运行时函数参数签名标识
        /// </summary>
        /// <param name="Name">函数名称</param>
        /// <param name="Types">函数的参数类型</param>
        public RuntimeMethodSign(string Name, Type[] Types):this(Name, (object[])Types)
        {
            IsInputParams = false;
        }

        private readonly bool IsInputParams;
        private readonly int HashCode;
        private readonly string InternalName;
        private readonly object[] InternalParams;
        
        public override int GetHashCode()
        {
            return HashCode;
        }



        public override bool Equals(object obj)
        {
            if (!(obj is RuntimeMethodSign))
            {
                return false;
            }

            var Object = (RuntimeMethodSign)obj;

            if (InternalName == Object.InternalName && InternalParams.Length == Object.InternalParams.Length)
            {
                if (IsInputParams)
                {
                    return TypeHelper.ParamsCompares((Type[])Object.InternalParams, InternalParams);
                }
                else if (Object.IsInputParams)
                {
                    return TypeHelper.ParamsCompares((Type[])InternalParams, Object.InternalParams);
                }
                else
                {
                    return TypeHelper.ParamsCompares((Type[])Object.InternalParams, (Type[])InternalParams);
                }
            }

            return false;


        }
    }
}